package commRedisList

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedis"
	"time"
)

type RedisListService struct {
	MaxSize int64 // 最大数量
}

func (e *RedisListService) Size(key string) (int64, error) {
	return commRedis.Client.LLen(key).Result()
}

func (e *RedisListService) IsBlock(key string) (bool, error) {
	val, err := e.Size(key)
	if err != nil {
		return true, err
	}

	return val >= e.MaxSize, nil
}

func (e *RedisListService) IsBusy(key string, percentage int64) (bool, error) {
	if percentage > 100 {
		percentage = 100
	}
	if percentage < 10 {
		percentage = 10
	}

	val, err := e.Size(key)
	if err != nil {
		return true, err
	}

	return val > e.MaxSize*percentage/100, nil
}

func (e *RedisListService) Push(key string, value string) error {
	return e.KPush(key, value)
}

func (e *RedisListService) KPush(key string, value string) error {
	_, err := commRedis.Client.RPush(key, value).Result()
	if err != nil {
		return err
	}

	return e.removeOverflow(key)
}

func (e *RedisListService) removeOverflow(key string) error {
	for true {
		val, err := commRedis.Client.LLen(key).Result()
		if err != nil {
			return err
		}

		if val > e.MaxSize {
			commRedis.Client.LPop(key)
			continue
		}

		return nil
	}

	return nil
}

func (e *RedisListService) GetAll(key string) ([]string, error) {
	return commRedis.Client.LRange(key, 0, e.MaxSize).Result()
}

func (e *RedisListService) GetRange(key string, start int64, end int64) ([]string, error) {
	return commRedis.Client.LRange(key, start, end).Result()
}

func (e *RedisListService) Pop(key string) (string, error) {
	return commRedis.Client.LPop(key).Result()
}

func (e *RedisListService) KBPop(key string, timeout time.Duration) (string, error) {
	val, err := commRedis.Client.BLPop(timeout, key).Result()
	if err != nil {
		return "", err
	}

	// 弹出的是数组大小为2，内容为topic和message
	valLen := len(val)
	if valLen < 2 {
		return "", nil
	}

	return val[valLen-1], nil
}

func (e *RedisListService) BPop(key string, timeout time.Duration) (string, error) {
	return e.KBPop(key, timeout)
}
